package com.turing.data.utils;

import cn.hutool.core.date.ChineseDate;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.turing.common.entity.JavaOcrParses;
import com.turing.common.entity.ParseContentVO;
import com.turing.common.entity.ParseTableVO;
import com.turing.common.entity.TextVO;
import com.turing.common.util.Log;
import com.turing.data.vo.out.review.TaskElementVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author fangyihang
 * @date Created in 2022/11/22 16:31
 */
public class ScriptTool {

    private static final Logger logger =  LoggerFactory.getLogger(ScriptTool.class);

    //忽略页码正则
    private static final Pattern IGNORE_PAGE_PATTERN = Pattern.compile("(\\d{1,3}|\\d{1,3}页)");


    //=======================================正则取值相关===================

    /**
     * regx为空字符串返回全文
     * regx不为空字符串，则在全文中进行匹配，匹配到了返回匹配的文本，否则返回空字符串
     * @param jsonText json
     * @param regx 正则
     * @param group 分组
     * @return
     */
    @SuppressWarnings("all")
    public static String getStrByAllText (String jsonText,String regx,int group){
        try {
            //进行对jsonText文件的解析
            List<TextVO> textVOList = JSON.parseArray(jsonText, TextVO.class);
            //每行数据进行遍历拼成整段文本(每页文本)
            StringBuffer stringBuffer = new StringBuffer();
            //开始遍历
            for (int i = 0; i < textVOList.size(); i++) {
                //获得当前页的段落
                List<TextVO.Paragraph> listParagraph = textVOList.get(i).getParagraphs();
                for (int j = 0; j < listParagraph.size(); j++) {
                    //获得每行集合
                    List<TextVO.Line> lines = listParagraph.get(j).getLines();
                    for (int k = 0; k < lines.size(); k++) {
                        TextVO.Line line = lines.get(k);
                        if (line == null){
                            continue;
                        }
                        String lineText =  line.getObjContent();
                        //拼接全文
                        stringBuffer.append(lineText);
                    }
                }

            }

            //获得全文本
            String allText = stringBuffer.toString();
            //匹配项为空就返回全文
            if (StringUtils.isBlank(regx)){
                return allText;
            }
            //匹配项不为空，返回匹配的内容
            //输入正则，拿到全文本进行匹配
            Pattern pattern = Pattern.compile(regx);
            Matcher matcher = pattern.matcher(allText);
            //定义一个真正展示的文本
            String valueText = "";
            //能匹配到：可以获得文本内容，和匹配内容在全文本起始位置(左闭右开)
            if (matcher.find()){
                valueText = matcher.group(group);
            }
            return valueText;

        } catch (Exception e) {
            Log.error("ScriptTool 中 getStrByAllText 方法 报错"+e);
        }

        //返回默认值
        return "";

    }


    //匹配全文并高亮
    public static TaskElementVO.DrawResultVO getAllResultByRegExp (String jsonText, String childTaskSn , String regx , List<String> startKeyList, List<String> endKeyList, Boolean startContains, Boolean endContains, int group){
        return getResultByRegExp(jsonText,childTaskSn,regx,startKeyList,endKeyList,startContains,endContains,group,false);
    }

    /**
     * 使用正则，匹配全文，并高亮
     * @param jsonText 模型传来的json文件
     * @param childTaskSn  任务id
     * @param regx  正则
     * @param startKeyList  前后关键字
     * @param endKeyList  前后关键字
     * @param startContains  是否包括关键字
     * @param endContains  是否包括关键字
     * @param group  正则所属组
     * @param onlyTable 是否只从表格中找
     * @return TaskElementVO.DrawResultVO
     */
    @SuppressWarnings("all")
    public static TaskElementVO.DrawResultVO getResultByRegExp (String jsonText, String childTaskSn , String regx , List<String> startKeyList, List<String> endKeyList, Boolean startContains, Boolean endContains, int group,Boolean onlyTable){
        //创建一个返回对象
        TaskElementVO.DrawResultVO drawResultVO = new TaskElementVO.DrawResultVO();
        try {
            //进行对jsonText文件的解析
            List<TextVO> textVOList = JSON.parseArray(jsonText, TextVO.class);
            //每行数据进行遍历拼成整段文本(每页文本)
            StringBuffer stringBuffer = new StringBuffer();
            //开始遍历
            for (int i = 0; i < textVOList.size(); i++) {
                //获得当前页的段落
                List<TextVO.Paragraph> listParagraph = textVOList.get(i).getParagraphs();
                for (int j = 0; j < listParagraph.size(); j++) {
                    //获得每行集合
                    List<TextVO.Line> lines = listParagraph.get(j).getLines();
                    for (int k = 0; k < lines.size(); k++) {
                        TextVO.Line line = lines.get(k);
                        if (line == null){
                            continue;
                        }
                        String lineText =  line.getObjContent();
                        //将页码(完全匹配)转为等量的特殊字符，然后再过
                        Matcher matcher = IGNORE_PAGE_PATTERN.matcher(lineText);
                        if (matcher.matches()){
                            for (int l = 0; l < lineText.length(); l++) {
                                stringBuffer.append("#");
                            }
                        }else {
                            //是否只使用表格
                            if (!onlyTable){
                                //拼接全文
                                stringBuffer.append(lineText);
                            }else {
                                //只从表格里正则
                                if (line.getObjType().contains("table")){
                                    //正常拼接
                                    stringBuffer.append(lineText);
                                }else {
                                    //非表格部分，用特殊字符替换
                                    for (int l = 0; l < lineText.length(); l++) {
                                        stringBuffer.append("#");
                                    }
                                }

                            }

                        }
                    }
                }

            }

            //获得全文本
            String allText = stringBuffer.toString();
            //输入正则，拿到全文本进行匹配
            Pattern pattern = Pattern.compile(regx);
            Matcher matcher = pattern.matcher(allText);
            //定义一个真正展示的文本
            String valueText = "";
            int start = 0;
            int end = 0;
            //能匹配到：可以获得文本内容，和匹配内容在全文本起始位置(左闭右开)
            if (matcher.find()){
                valueText = matcher.group(group);
                start = matcher.start(group);
                end = matcher.end(group);
            }
            //没有匹配到直接返回的文本为空字符串
            if("".equals(valueText)){
                drawResultVO.setText("");
                drawResultVO.setBusinessValue("");
                drawResultVO.setType(1);
                return drawResultVO;
            }
            //通过start和end判断返回经过的行号
            //关键词进行偏移(前后均不包括关键字)
            int startOffset = 0;
            int endOffset = 0;
            String startKey = "";
            String endKey = "";
            //对传入的关键字进行遍历
            if(!startKeyList.isEmpty()){
                for (int i = 0; i < startKeyList.size(); i++) {
                    if (valueText.contains(startKeyList.get(i))){
                        startKey = startKeyList.get(i);
                        break;
                    }
                }
            }
            if(!endKeyList.isEmpty()){
                for (int i = 0; i < endKeyList.size(); i++) {
                    if (valueText.contains(endKeyList.get(i))){
                        endKey = endKeyList.get(i);
                        break;
                    }
                }
            }

            //根据关键字重新计算起始位置和文本内容
            if(!"".equals(startKey)&&valueText.contains(startKey)){
                if(startContains){
                    startOffset = valueText.indexOf(startKey);
                    start = start+startOffset;
                }else {
                    startOffset = valueText.indexOf(startKey)+startKey.length();
                    start = start+startOffset;
                }
            }
            if(!"".equals(endKey)&&valueText.contains(endKey)){
                if (endContains){
                    endOffset = valueText.lastIndexOf(endKey)+endKey.length() - valueText.length();
                    end = end + endOffset;
                }else{
                    endOffset = valueText.lastIndexOf(endKey) - valueText.length();
                    end = end + endOffset;
                }
            }
            valueText = valueText.substring(startOffset,valueText.length()+endOffset);
            //装匹配到的行号
            List<String> lineIDs = new ArrayList<>();
            List<Integer> pos_info = new ArrayList<>();

            //通过起始位置：了解在第几页，并拿到该页信息（只支持在同一页）
            int pageId = -1;
            List<TextVO.Paragraph> trueParagraphs = new ArrayList<>();
            for (int i = 0; i < textVOList.size(); i++) {
                //获得当前页的段落
                int pageStartIndex = textVOList.get(i).getPageStartIndex();
                int pageEndIndex = textVOList.get(i).getPageEndIndex();
                //在同一页(不在同一页就返回,当前起始位置到该页最后一个字符)
                if(start>=pageStartIndex && end <= pageEndIndex){
                    pageId = textVOList.get(i).getPageNo();
                    trueParagraphs = textVOList.get(i).getParagraphs();
                }else if(start>=pageStartIndex && start<pageEndIndex && end > pageEndIndex){
                    end = pageEndIndex;
                    pageId = textVOList.get(i).getPageNo();
                    trueParagraphs = textVOList.get(i).getParagraphs();
                }
            }

            for (int j = 0; j < trueParagraphs.size(); j++) {
                //获得每行集合
                List<TextVO.Line> lines = trueParagraphs.get(j).getLines();
                //进行遍历
                for (int l = 0; l < lines.size(); l++) {
                    //每行的起止字符的全局位置[indexStart,indexEnd)
                    TextVO.Line line = lines.get(l);
                    int indexStart = line.getLineStartIndex();
                    int indexEnd = line.getLineEndIndex();
                    //大于等于行起始行,小于结束行
                    if(start>=indexStart && start<indexEnd){
                        lineIDs.add(line.getLineId());
                        pos_info.add(start-indexStart);
                    }
                    if(start<indexStart && end>indexEnd){
                        lineIDs.add(line.getLineId());
                    }
                    if(end>indexStart && end<=indexEnd){
                        lineIDs.add(line.getLineId());
                        //pos_info.add(end-indexStart) //产品化需要减1
                        pos_info.add(end-indexStart-1);
                    }
                }

            }


            //对lineIDS进行去重，返回一行时会出现重复问题
            lineIDs = lineIDs.stream().distinct().collect(Collectors.toList());

            //返回最后结果
            drawResultVO.setPage(pageId);
            drawResultVO.setType(1);
            drawResultVO.setText(valueText);
            drawResultVO.setBusinessValue(valueText);
            drawResultVO.setStart(start);
            drawResultVO.setEnd(end);
            drawResultVO.setChildTaskSn(childTaskSn);
            drawResultVO.setPos_info(pos_info);
            drawResultVO.setPara_info(lineIDs);
            return drawResultVO;
        } catch (Exception e) {
            Log.error("ScriptTool 中 getResultByRegExp 方法 报错"+e);
        }

        //返回默认值
        drawResultVO.setText("");
        drawResultVO.setBusinessValue("");
        drawResultVO.setType(1);
        return drawResultVO;

    }


    //匹配单行内容
    @SuppressWarnings("all")
    public static TaskElementVO.DrawResultVO getResultByRegExpInLine (String jsonText, String childTaskSn , String regx , int group,Boolean onlyTable){
        //创建一个返回对象
        TaskElementVO.DrawResultVO drawResultVO = new TaskElementVO.DrawResultVO();
        try {
            //进行对jsonText文件的解析
            List<TextVO> textVOList = JSON.parseArray(jsonText, TextVO.class);
            //匹配的坐标
            int start = 0;
            int end = 0;
            String valueText = "";
            //开始遍历
            OK:
            for (int i = 0; i < textVOList.size(); i++) {
                //获得当前页的段落
                List<TextVO.Paragraph> listParagraph = textVOList.get(i).getParagraphs();
                for (int j = 0; j < listParagraph.size(); j++) {
                    //获得每行集合
                    List<TextVO.Line> lines = listParagraph.get(j).getLines();
                    for (int k = 0; k < lines.size(); k++) {
                        TextVO.Line line = lines.get(k);
                        if (line == null){
                            continue;
                        }
                        String lineText =  line.getObjContent();
                        Pattern pattern = Pattern.compile(regx);
                        //是否只使用表格
                        if (!onlyTable){
                            //输入正则，拿到当前行进行匹配
                            Matcher matcher = pattern.matcher(lineText);
                            //能匹配到：可以获得文本内容，和匹配内容在全文本起始位置(左闭右开)
                            if (matcher.find()){
                                valueText = matcher.group(group);
                                start = matcher.start(group) + lines.get(k).getLineStartIndex();
                                end = matcher.end(group) + lines.get(k).getLineStartIndex();
                                break OK;
                            }
                        }else {
                            //只从表格里正则
                            if (line.getObjType().contains("table")){
                                //输入正则，拿到当前行进行匹配
                                Matcher matcher = pattern.matcher(lineText);
                                //能匹配到：可以获得文本内容，和匹配内容在全文本起始位置(左闭右开)
                                if (matcher.find()){
                                    valueText = matcher.group(group);
                                    start = matcher.start(group) + lines.get(k).getLineStartIndex();
                                    end = matcher.end(group) + lines.get(k).getLineStartIndex();
                                    break OK;
                                }
                            }

                        }
                    }
                }

            }

            //没有匹配到直接返回的文本为空字符串
            if("".equals(valueText)){
                drawResultVO.setText("");
                drawResultVO.setBusinessValue("");
                drawResultVO.setType(1);
                return drawResultVO;
            }

            //装匹配到的行号
            List<String> lineIDs = new ArrayList<>();
            List<Integer> pos_info = new ArrayList<>();

            //通过起始位置：了解在第几页，并拿到该页信息（只支持在同一页）
            int pageId = -1;
            List<TextVO.Paragraph> trueParagraphs = new ArrayList<>();
            for (int i = 0; i < textVOList.size(); i++) {
                //获得当前页的段落
                int pageStartIndex = textVOList.get(i).getPageStartIndex();
                int pageEndIndex = textVOList.get(i).getPageEndIndex();
                //在同一页(不在同一页就返回,当前起始位置到该页最后一个字符)
                if(start>=pageStartIndex && end <= pageEndIndex){
                    pageId = textVOList.get(i).getPageNo();
                    trueParagraphs = textVOList.get(i).getParagraphs();
                }else if(start>=pageStartIndex && start<pageEndIndex && end > pageEndIndex){
                    end = pageEndIndex;
                    pageId = textVOList.get(i).getPageNo();
                    trueParagraphs = textVOList.get(i).getParagraphs();
                }
            }

            for (int j = 0; j < trueParagraphs.size(); j++) {
                //获得每行集合
                List<TextVO.Line> lines = trueParagraphs.get(j).getLines();
                //进行遍历
                for (int l = 0; l < lines.size(); l++) {
                    //每行的起止字符的全局位置[indexStart,indexEnd)
                    TextVO.Line line = lines.get(l);
                    int indexStart = line.getLineStartIndex();
                    int indexEnd = line.getLineEndIndex();
                    //大于等于行起始行,小于结束行
                    if(start>=indexStart && start<indexEnd){
                        lineIDs.add(line.getLineId());
                        pos_info.add(start-indexStart);
                    }
                    if(start<indexStart && end>indexEnd){
                        lineIDs.add(line.getLineId());
                    }
                    if(end>indexStart && end<=indexEnd){
                        lineIDs.add(line.getLineId());
                        //pos_info.add(end-indexStart) //产品化需要减1
                        pos_info.add(end-indexStart-1);
                    }
                }

            }


            //对lineIDS进行去重，返回一行时会出现重复问题
            lineIDs = lineIDs.stream().distinct().collect(Collectors.toList());

            //返回最后结果
            drawResultVO.setPage(pageId);
            drawResultVO.setType(1);
            drawResultVO.setText(valueText);
            drawResultVO.setBusinessValue(valueText);
            drawResultVO.setStart(start);
            drawResultVO.setEnd(end);
            drawResultVO.setChildTaskSn(childTaskSn);
            drawResultVO.setPos_info(pos_info);
            drawResultVO.setPara_info(lineIDs);
            return drawResultVO;
        } catch (Exception e) {
            Log.error("ScriptTool 中 getResultByRegExp 方法 报错"+e);
        }

        //返回默认值
        drawResultVO.setText("");
        drawResultVO.setBusinessValue("");
        drawResultVO.setType(1);
        return drawResultVO;

    }


    //==================================表格里拿值相关(通过冒号切分)==================


    /**
     * 当前表满足表头时，将当前表的每行数据返回，只拿一张表
     * @param useTableReg 表头
     * @param count 当前表满足的表头数量
     * @return
     */
    public static List<TextVO.Line> checkTableByTitle(String jsonText,String useTableReg,int count) {
        List<TextVO.Line> tableLines = new ArrayList<TextVO.Line>();
        //添加表的锁
        boolean addClock = false;
        //进行对jsonText文件的解析
        List<TextVO> textVOList = JSON.parseArray(jsonText, TextVO.class);
        //开始遍历
        try {
            for (int i = 0; i < textVOList.size(); i++) {
                //获得当前页的段落
                List<TextVO.Paragraph> listParagraph = textVOList.get(i).getParagraphs();
                for (int j = 0; j < listParagraph.size(); j++) {
                    //获得每行集合
                    List<TextVO.Line> lines = listParagraph.get(j).getLines();
                    for (int k = 0; k < lines.size(); k++) {
                        TextVO.Line line = lines.get(k);
                        if (line!=null){
                            //table类型
                            if (line.getObjType().contains("table")){
                                if (addClock){
                                    //表里面的内容
                                    tableLines.add(lines.get(k));
                                }
                                //table是否满足定义的表头
                                if (StringUtils.isNotBlank(line.getObjContent())){
                                    Pattern pattern = Pattern.compile(useTableReg);
                                    Matcher matcher = pattern.matcher(line.getObjContent());
                                    int number = 0;
                                    while (matcher.find()){
                                        number ++;
                                    }

                                    //匹配的表头数量大于3，表示使用此表
                                    if (number >= count){
                                        tableLines.add(lines.get(k));
                                        addClock = true;
                                    }

                                }

                            }else {
                                //不是表（保证了只会拿一张表里的数据）
                                addClock = false;
                            }
                        }
                    }

                }

            }
        } catch (Exception e) {
            Log.error("ScriptTool checkTableByTitle方法错误"+e);
        }

        return tableLines;
    }

    //根据表头获得表格中同列的结果
    //先匹配到表头获得index，再返回同列集合

    /**
     * 根据表头获得表格中同列的结果
     * 实现：先匹配到表头获得index，再返回同列集合
     * 需要配合checkTableByTitle方法使用
     * @param taskSn 任务id
     * @param tableLines  checkTableByTitle方法获得的表的每行内容集合
     * @param titleReg 匹配的表头
     * @return
     */
    @SuppressWarnings("all")
    public static List<TaskElementVO.DrawResultVO> getValueByTableTitle(String taskSn,List<TextVO.Line> tableLines,String titleReg){
        //表头所在行
        int row = -1;
        //表头所在列
        int index = -1;
        OK:
        try {
            for (int i = 0; i < tableLines.size(); i++) {
                TextVO.Line line = tableLines.get(i);
                if (line!=null && StringUtils.isNotBlank(line.getObjContent())){
                    List<String> tableLine = Arrays.asList(line.getObjContent().split(":"));
                    for (int j = 0; j < tableLine.size(); j++) {
                        if (StringUtils.isNotBlank(tableLine.get(j))){
                            Pattern pattern = Pattern.compile(titleReg);
                            Matcher matcher = pattern.matcher(tableLine.get(j));
                            if (matcher.find()){
                                index = j;
                                row = i;
                                break OK;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            Log.error("ScriptTool getValueByTableTitle 方法报错："+e);
        }

        //找到表头下方的值
        List<TaskElementVO.DrawResultVO>  drawResultVOS = new ArrayList<>();
        if (index != -1 && row != -1){
            //获得的值需要在表头下方
            try {
                for (int i = 0; i < tableLines.size(); i++) {
                    if (i > row){
                        TextVO.Line line = tableLines.get(i);
                        if (line!=null && StringUtils.isNotBlank(line.getObjContent())) {
                            List<String> tableLine = Arrays.asList(line.getObjContent().split(":"));
                            TaskElementVO.DrawResultVO draw = new TaskElementVO.DrawResultVO();
                            int lineStart = 0;
                            int lineEnd = 0;

                            //有当前列的值就输出，否则就默认为空
                            if (tableLine.size()>index){
                                String val = tableLine.get(index);
                                //查找字符第n次出现的位置
                                lineStart = StringUtils.ordinalIndexOf(line.getObjContent(),":",index)+1;
                                lineEnd = lineStart + val.length() -1;
                                draw.setText(val);
                            }else {
                                draw.setText("");
                            }

                            //设置高亮
                            draw.setBusinessValue(draw.getText());
                            draw.setType(1);
                            draw.setChildTaskSn(taskSn);
                            draw.setPage(Integer.parseInt(tableLines.get(i).getLineId().split("_")[1]));
                            draw.setPos_info(Arrays.asList(lineStart,lineEnd));
                            draw.setPara_info(Arrays.asList(tableLines.get(i).getLineId()));
                            drawResultVOS.add(draw);

                        }
                    }
                }
            } catch (NumberFormatException e) {
                Log.error("ScriptTool getValueByTableTitle 方法报错："+e);
            }
        }

        //默认返回一个结果为空的list
        return drawResultVOS;
    }




    //==================================表格里拿值相关(table)==================


    //当前行符合正则，并满足匹配数量，则从当前行开始进行拆分，拆分成新的表
    public static List<ParseTableVO> splitParseTableVOByLineStrRegx(ParseTableVO parseTableVO,String lineStrRegx,int count) {
        return splitParseTableVOByLineStrRegx(parseTableVO, lineStrRegx, count, ":");
    }

    /**
     * 当前行符合正则，并满足匹配数量，则从当前行开始进行拆分，拆分成新的表
     * 注意，表格切分后，表格的描述会为空
     * @param parseTableVO 初始表
     * @param lineStrRegx 当前行满足的正则（会触发拆表逻辑）
     * @param count 当前行满足正则的次数
     * @param joinChar 每行单元格内容之间拼接的特殊字符，可以为空
     * @return 拆分后的表格集合
     */
    public static List<ParseTableVO> splitParseTableVOByLineStrRegx(ParseTableVO parseTableVO,String lineStrRegx,int count,String joinChar) {
        List<ParseTableVO> tableVOS = new ArrayList<>();

        if (parseTableVO != null && parseTableVO.getTable() != null && parseTableVO.getTable().size() > 0){
            //这里做拆分表格的逻辑
            if (StringUtils.isNotBlank(lineStrRegx)){

                List<ParseContentVO> table = parseTableVO.getTable();
                //table根据行id进行分组 （两种分组方式）
                // ==注意，使用行id进行分组时，可能导致分组乱序，使用行号进行分组==
                //Log.info("分组："+table.stream().collect(Collectors.groupingBy({item -> item.getAt("lineId")})))
                //Map<String,List<ParseContentVO>> groupTable = table.groupBy({ item -> item.getLineId() })
                Map<Integer,List<ParseContentVO>> groupTable = table.stream().collect(Collectors.groupingBy(item -> item.getRowNum().get(0)));

                //拿出所有的键，并排序
                List<Integer> keys = new ArrayList<>();
                for (Map.Entry<Integer,List<ParseContentVO>> entry : groupTable.entrySet() ) {
                    keys.add(entry.getKey());
                }

                //排序
                keys = keys.stream().sorted().collect(Collectors.toList());

                //遍历所有的分组 （注意表格拆分后，拆分后的表格无序）
                //默认放一个空的ParseTableVO
                ParseTableVO defaultParseTableVO = new ParseTableVO();
                List<ParseContentVO> defaultTable = new ArrayList<>();
                defaultParseTableVO.setTable(defaultTable);
                tableVOS.add(defaultParseTableVO);

                //遍历keys，从map中获得内容
                for (int i = 0; i < keys.size(); i++) {
                    try {
                        List<ParseContentVO> line = groupTable.get(keys.get(i));
                        //获得每行的内容
                        List<String> collect = line.stream().map(ParseContentVO::getValue).collect(Collectors.toList());
                        String join = StringUtils.join(collect,joinChar);
                        //行满足正则的次数
                        int number = 0;
                        Pattern pattern = Pattern.compile(lineStrRegx);
                        Matcher matcher = pattern.matcher(join);
                        while (matcher.find()){
                            number++;
                        }

                        if (number >= count){
                            //触发拆分表条件（注意，当前表格第一行触发的情况，我们需要在最后对空值做个过滤）
                            //每次触发，就往集合里放一个ParseTableVO
                            ParseTableVO newParseTableVO = new ParseTableVO();
                            List<ParseContentVO> newTable = new ArrayList<>();
                            newParseTableVO.setTable(newTable);
                            tableVOS.add(newParseTableVO);
                        }

                        //每次都把数据放入到tableVOS的最后一个对象中
                        ParseTableVO currentParseTableVO = tableVOS.get(tableVOS.size() - 1);

                        if (currentParseTableVO.getTable()!=null){
                            List<ParseContentVO> currentTable = currentParseTableVO.getTable();
                            currentTable.addAll(line);
                        }
                    } catch (Exception e) {
                        Log.error("ScriptTool splitParseTableVOByLineStrRegx 方法报错"+e);
                    }
                }

                //过滤结果
                tableVOS = tableVOS.stream()
                        .filter(item -> item.getTable()!=null && item.getTable().size() > 0)
                        .collect(Collectors.toList());

            }else {
                //如果拆分规则是空，则返回原来的表
                tableVOS.add(parseTableVO);
            }

            //返回拆分后的表
            return tableVOS;
        }
        return  tableVOS;
    }


    //根据指定规则，判断是否使用当前表格
    public static boolean findParseTableVO(ParseTableVO parseTableVO,String onlyCellRegx,String countCellRegx,int count,String lineStrRegx,int lineCount) {
        return findParseTableVO(parseTableVO, onlyCellRegx, countCellRegx, count, lineStrRegx, lineCount,":");
    }


    /**
     * 根据指定规则，判断是否使用当前表格
     * @param parseTableVO 表
     * @param onlyCellRegx 只要有一个单元格应该匹配的内容
     * @param countCellRegx 指定数量的单元格满足条件才进行匹配
     * @param count 指定的数量
     * @param lineStrRegx 指定匹配次数的当前行正则，满足数量则true
     * @param lineCount  该行的匹配次数
     * @param joinChar 每行单元格内容之间拼接的特殊字符，可以为空
     * @return
     */
    public static boolean findParseTableVO(ParseTableVO parseTableVO,String onlyCellRegx,String countCellRegx,int count,String lineStrRegx,int lineCount,String joinChar) {
        List<ParseContentVO> table = parseTableVO.getTable();
        //使用当前表--单元格应该匹配某内容
        int number = 0;
        for (int i = 0; i < table.size(); i++) {
            //当前单元格的内容
            ParseContentVO contentVO = table.get(i);
            //只要有一个单元格应该匹配的内容
            if (StringUtils.isNotBlank(onlyCellRegx)){
                Pattern pattern = Pattern.compile(onlyCellRegx);
                Matcher matcher = pattern.matcher(contentVO.getValue());
                if (matcher.find()){
                    return true;
                }
            }

            if (StringUtils.isNotBlank(countCellRegx)){
                Pattern pattern = Pattern.compile(countCellRegx);
                Matcher matcher = pattern.matcher(contentVO.getValue());
                if (matcher.find()){
                    number++;
                }
                if (number >= count){
                    return true;
                }
            }
        }
        //指定匹配次数的当前行正则
        if (StringUtils.isNotBlank(lineStrRegx)){
            Map<String,List<ParseContentVO>> groupTable = table.stream().collect(Collectors.groupingBy(ParseContentVO::getLineId));
            for (Map.Entry<String,List<ParseContentVO>> entry : groupTable.entrySet() ) {
                List<ParseContentVO> line = entry.getValue();
                //获得每行的内容
                List<String> collect = line.stream().map(ParseContentVO::getValue).collect(Collectors.toList());
                String join = StringUtils.join(collect, joinChar);
                //行满足正则的次数
                int number2 = 0;
                Pattern pattern = Pattern.compile(lineStrRegx);
                Matcher matcher = pattern.matcher(join);
                while (matcher.find()) {
                    number2++;
                }
                if (number2 >= lineCount){
                    return true;
                }
            }
        }
        //默认不取当前表
        return false;
    }


    /**
     * 获得结构化数据表格的描述
     * 获得当前表的描述(默认后5行，不能超过10)。作用：可以用来匹配单位，也可以用来决定是否选择当前表
     * @param tableVO 表格
     * @return 表格描述
     */
    public static String getDefaultTableDescribe(ParseTableVO tableVO){
        return getTableDescribe(tableVO,5);
    }

    public static String getTableDescribe(ParseTableVO tableVO,int count){
        StringBuilder builder = new StringBuilder();
        List<JavaOcrParses> ocr = tableVO.getOcr();
        try {
            if (ocr!=null && ocr.size() > 0){
                int row = count;
                if (ocr.size() > row){
                    ocr = ocr.subList(ocr.size() - row,ocr.size());
                }

                for (int i = 0; i < ocr.size(); i++) {
                    JavaOcrParses textLine = ocr.get(i);
                    builder.append(textLine.getObjContent());
                }

                return builder.toString();
            }
        } catch (Exception e) {
            Log.error("ScriptTool 方法 getTableDescribe 出现错误"+e);
        }
        return "";

    }

    /**
     * 从当前表格中获取需要的内容
     * 默认不过滤空白字符
     */
    public static List<ParseContentVO> getResultByReg(ParseTableVO tableVO, String topReg ,String topAll, String leftReg, String leftAll, String valReg,String valAll, String noValReg, String noTopReg, String noLeftReg){
        return getResultByReg(tableVO, topReg, topAll, leftReg, leftAll, valReg, valAll, noValReg, noTopReg, noLeftReg,false);
    }

    /**
     * 从当前表格中获取需要的内容
     * @param tableVO 结构化后的表格
     * @param topReg 顶部标题匹配
     * @param topAll 顶部标题全量匹配
     * @param leftReg 左部标题匹配
     * @param leftAll 左部标题全量匹配
     * @param valReg  单元格内容满足正则的值
     * @param valAll  单元格内容满足正则且全量匹配
     * @param noValReg  排除满足正则的值
     * @param noTopReg 排除顶部标题满足正则的值
     * @param noLeftReg 排除左部标题满足正则的值
     * @param filterBlank 是否过滤空白字符
     * @return
     */
    public static List<ParseContentVO> getResultByReg(ParseTableVO tableVO, String topReg ,String topAll, String leftReg, String leftAll, String valReg,String valAll, String noValReg, String noTopReg, String noLeftReg,boolean filterBlank){

        List<ParseContentVO> tableInit = tableVO.getTable();

        //深克隆当前table
        List<ParseContentVO> table = null;
        try {
            table = deepCopy(tableInit);
        } catch (IOException | ClassNotFoundException e) {
            Log.error("ScriptTool 深拷贝对象异常："+e);
        }

        List<ParseContentVO> result = new ArrayList<>();
        if (table!=null && table.size() > 0) {
            try {
                result = table.stream().filter(tableLine -> {
                    //满足顶部标题
                    if (StringUtils.isNotBlank(topReg) || StringUtils.isNotBlank(topAll)) {
                        List<String> topTitles = tableLine.getTopTitleList();
                        if (topTitles!=null && topTitles.size() > 0) {
                            //任何一个都匹配不到返回false
                            boolean anyMatcher = false;
                            //遍历表头，完全匹配
                            for (int i = 0; i < topTitles.size(); i++) {
                                //模糊匹配
                                String topTitle = topTitles.get(i);
                                //对当前单元格的标题去空格
                                topTitle = getStrNoBlank(topTitle);
                                if (StringUtils.isNotBlank(topReg)){
                                    Pattern pattern = Pattern.compile(topReg);
                                    Matcher matcher = pattern.matcher(topTitle);
                                    if (matcher.find()){
                                        anyMatcher = true;
                                        //匹配到了就直接退出，不再匹配
                                        break;
                                    }
                                }

                                //全量匹配
                                if (StringUtils.isNotBlank(topAll)){
                                    Pattern pattern = Pattern.compile(topAll);
                                    Matcher matcherAll = pattern.matcher(topTitle);
                                    if (matcherAll.matches()){
                                        anyMatcher = true;
                                        //匹配到了就直接退出，不再匹配
                                        break;
                                    }
                                }

                            }

                            //找不到，拦截
                            if (!anyMatcher){
                                return false;
                            }

                        } else {
                            //标题为空，拦截
                            return false;
                        }
                    }
                    //满足左部标题
                    if (StringUtils.isNotBlank(leftReg) || StringUtils.isNotBlank(leftAll)) {
                        List<String> leftTitles = tableLine.getLeftTitleList();
                        if (leftTitles!=null && leftTitles.size() > 0) {
                            //任何一个都匹配不到返回false
                            boolean anyMatcher = false;
                            //遍历表头，完全匹配
                            for (int i = 0; i < leftTitles.size(); i++) {

                                String leftTitle = leftTitles.get(i);
                                leftTitle = getStrNoBlank(leftTitle);
                                //模糊匹配
                                if (StringUtils.isNotBlank(leftReg)){
                                    Pattern pattern = Pattern.compile(leftReg);
                                    Matcher matcher = pattern.matcher(leftTitle);
                                    if (matcher.find()){
                                        anyMatcher = true;
                                        //匹配到了就直接退出，不再匹配
                                        break;
                                    }
                                }

                                //全量匹配
                                if (StringUtils.isNotBlank(leftAll)){
                                    Pattern pattern = Pattern.compile(leftAll);
                                    Matcher matcherAll = pattern.matcher(leftTitle);
                                    if (matcherAll.matches()){
                                        anyMatcher = true;
                                        //匹配到了就直接退出，不再匹配
                                        break;
                                    }
                                }

                            }

                            //找不到，拦截
                            if (!anyMatcher){
                                return false;
                            }

                        } else {
                            //标题为空，拦截
                            return false;
                        }
                    }
                    //不应该出现的头部标题
                    if (StringUtils.isNotBlank(noTopReg)) {
                        List<String> topTitles = tableLine.getTopTitleList();
                        if (topTitles!=null && topTitles.size() > 0) {
                            for (String topTitle : topTitles) {
                                //对当前单元格去空格
                                topTitle = getStrNoBlank(topTitle);
                                if (StringUtils.isNotBlank(topTitle)) {
                                    Pattern pattern = Pattern.compile(noTopReg);
                                    Matcher matcher = pattern.matcher(topTitle);
                                    if (matcher.find()) {
                                        //标题满足要求，拦截
                                        return false;
                                    }
                                }
                            }
                        }

                    }
                    //不应该出现的左部标题
                    if (StringUtils.isNotBlank(noLeftReg)) {
                        List<String> leftTitleList = tableLine.getLeftTitleList();
                        if (leftTitleList!=null && leftTitleList.size() > 0) {
                            for (String leftTitle : leftTitleList) {
                                leftTitle = getStrNoBlank(leftTitle);
                                if (StringUtils.isNotBlank(leftTitle)) {
                                    Pattern pattern = Pattern.compile(noLeftReg);
                                    Matcher matcher = pattern.matcher(leftTitle);
                                    if (matcher.find()) {
                                        //标题满足要求，拦截
                                        return false;
                                    }
                                }
                            }
                        }

                    }
                    //满足值 (支持模糊匹配和全量匹配)
                    if (StringUtils.isNotBlank(valReg) || StringUtils.isNotBlank(valAll)) {
                        String value = tableLine.getValue();
                        value = getStrNoBlank(value);
                        if (StringUtils.isNotBlank(value)) {
                            //模糊匹配
                            if (StringUtils.isNotBlank(valReg)){
                                Pattern pattern = Pattern.compile(valReg);
                                Matcher matcher = pattern.matcher(value);
                                if (!matcher.find()) {
                                    //值不满足要求，拦截
                                    return false;
                                }
                            }
                            //全量匹配
                            if (StringUtils.isNotBlank(valAll)){
                                Pattern pattern = Pattern.compile(valAll);
                                Matcher matcher = pattern.matcher(value);
                                if (!matcher.matches()) {
                                    //值不满足要求，拦截
                                    return false;
                                }
                            }

                        }
                        //值如果是空字符串，默认通过，如果有需要再过滤
                    }
                    //不满足值
                    if (StringUtils.isNotBlank(noValReg)) {
                        String value = tableLine.getValue();
                        value = getStrNoBlank(value);
                        if (StringUtils.isNotBlank(value)) {
                            Pattern pattern = Pattern.compile(noValReg);
                            Matcher matcher = pattern.matcher(value);
                            if (matcher.find()) {
                                //值不应该匹配到这个内容，拦截
                                return false;
                            }
                        }
                        //值如果是空字符串，默认通过，如果有需要再过滤
                    }

                    return true;
                }).collect(Collectors.toList());
            } catch (Exception e) {
                Log.error("ScriptTool getResultByReg 方法错误："+e);
            }
        }

        //过滤空白字符
        if (filterBlank){
            result = result.stream().filter(item -> StringUtils.isNotBlank(item.getValue())).collect(Collectors.toList());
        }

        return result;

    }

    /**
     * 返回连续的单元格结果集
     * @param resultParseContentVO 得到的所有单元格
     * @param isHorizontal 是否是横表
     */
    public static List<ParseContentVO> returnContinuityCells(List<ParseContentVO> resultParseContentVO,boolean isHorizontal){
        //两个值以上才有使用这个方法的必要
        if (resultParseContentVO!=null && resultParseContentVO.size() > 1){
            List<ParseContentVO> continuityContentVO = new ArrayList<>();
            if (!isHorizontal){
                //竖表的处理
                try {
                    for (int i = 0; i <resultParseContentVO.size(); i++) {
                        //第一个除外
                        if (i!=0){
                            //得到当前cell的行
                            Integer currentRow = resultParseContentVO.get(i).getRowNum().get(0);
                            //得到上一个cell行
                            Integer row = resultParseContentVO.get(i-1).getRowNum().get(1);
                            if (currentRow - row > 1){
                                //不连续了，直接返回结果
                                return continuityContentVO;
                            }
                            //符合连续的，加入
                            continuityContentVO.add(resultParseContentVO.get(i));
                        }else {
                            continuityContentVO.add(resultParseContentVO.get(i));
                        }
                    }
                } catch (Exception e) {
                    Log.error("ScriptTool returnContinuityCells 方法错误"+e);
                }

            }
        }
        return resultParseContentVO;
    }



    //===================================格式相关=======================

    /**
     * 对金额进行统一格式处理
     * @param amount 金额
     * @return String
     */
    public static String formatNumber(String amount){
        amount = getAmountSmall(amount);
        //金额格式化
        if (amount.length() > 5){
            //四个小数点
            String special = amount.substring(amount.length() - 1 -4,amount.length()-4);
            if (".".equals(special)){
                DecimalFormat decimalFormat = new DecimalFormat("###,##0.0000");
                try {
                    amount = decimalFormat.format(Double.parseDouble(String.valueOf(amount)));
                    return amount;
                } catch (Exception exception) {
                    Log.error("转换金额失败>>"+exception);
                }
            }

        }

        if (amount.length() > 3){
            String special = amount.substring(amount.length() - 1 -2,amount.length()-2);
            //两个小数点
            if (".".equals(special)){
                DecimalFormat decimalFormat = new DecimalFormat("###,##0.00");
                try {
                    amount = decimalFormat.format(Double.parseDouble(String.valueOf(amount)));
                    return amount;
                } catch (Exception exception) {
                    Log.error("转换金额失败>>"+exception);
                }
            }
        }


        return amount;
    }

    private static String getAmountSmall(String text){
        //判断是否有小数 ,1表示需要弄成小数点格式,否则按整数补全小数处理
        int type = 0;
        if (text.contains(".")){
            type = 1;
        }else if (text.contains(",") || text.contains("，")){
            //考虑两位小数的情况12,000,12
            if (text.length() > 3){
                //倒数第二个是,，则默认type=1
                String special = text.substring(text.length() - 1 -2,text.length()-2);
                if ("，".equals(special) || ",".equals(special)){
                    type = 1;
                }
            }

            //考虑四位小数的情况1,110.0000
            if (text.length() > 5){
                //倒数第二个是,，则默认type=1
                String special = text.substring(text.length() - 1 -4,text.length()-4);
                if ("，".equals(special) || ",".equals(special) || ".".equals(special)){
                    type = 2;
                }
            }
        }

        if (type == 1){
            //考虑四位小数的情况1,110.0000
            if (text.length() > 5){
                //倒数第二个是,，则默认type=1
                String special = text.substring(text.length() - 1 -4,text.length()-4);
                if ("，".equals(special) || ",".equals(special) || ".".equals(special)){
                    type = 2;
                }
            }
        }

        String modelValue = text
                .replaceAll("[,，.。：:+]","")
                .replaceAll("([\\u4e00-\\u9fa5]|[a-z]|[A-Z])","");
        //去除特殊情况
        if (modelValue.length()<=2){
            return text;
        }

        String result = "";

        if (type == 1){
            //两位小数进入：
            //获得末尾两个数字
            String last = modelValue.substring(modelValue.length()-2);
            //除去末尾两个数字
            String str2 = modelValue.substring(0,modelValue.length()-2);
            result = str2+"."+last;
        }else if (type == 2 ){
            //四位小数进入
            //获得末尾两个数字
            String last = modelValue.substring(modelValue.length()-4);
            //除去末尾两个数字
            String str2 = modelValue.substring(0,modelValue.length()-4);
            result = str2+"."+last;
        } else {
            result = modelValue;
        }

        return result;
    }


    //简单的数字格式处理，未考虑到四个小数点的情况
    public static String formatNumberSimple(String amount){
        amount = getAmountSmall(amount);
        //金额格式化
        DecimalFormat decimalFormat = new DecimalFormat("###,##0.00");
        try {
            amount = decimalFormat.format(Double.parseDouble(String.valueOf(amount)));
        } catch (Exception exception) {
            Log.error("转换金额失败>>"+exception);
        }
        return amount;
    }

    //简单的数字处理，未考虑四个小数点的情况
    private static String getAmountSmallSimple(String text){
        //判断是否有小数 ,1表示需要弄成小数点格式,否则按整数补全小数处理
        int type = 0;
        if (text.contains(".")){
            type = 1;
        }
        String modelValue = text
                .replaceAll("[,，.。：:+]","")
                .replaceAll("([\\u4e00-\\u9fa5]|[a-z]|[A-Z])","");
        //去除特殊情况
        if (modelValue.length()<=2){
            return text;
        }

        String result = "";

        if (type == 1){
            //获得末尾两个数字
            String last = modelValue.substring(modelValue.length()-2);
            //除去末尾两个数字
            String str2 = modelValue.substring(0,modelValue.length()-2);
            result = str2+"."+last;
        }else {
            result = modelValue;
        }

        return result;
    }

    //格式化日期样式
    @SuppressWarnings("all")
    public static String formatDate(String dateStr){
        Pattern pattern = Pattern.compile("(2\\d{3})[^\\d]?([01][0-9]|[0-9])[^\\d]?([0123][0-9]|[0-9])");
        Matcher matcher = pattern.matcher(dateStr);
        String date = dateStr;
        String year = "";
        String month = "";
        String day = "";
        if (matcher.find()){
            year = matcher.group(1);
            month = matcher.group(2);
            if (month.length() == 1){
                month = "0"+month;
            }
            day = matcher.group(3);
            if (day.length() == 1){
                day = "0"+day;
            }
            date = year + "-" + month + "-" + day;
        }
        return date;
    }


    /**
     * 去除空字符串
     */
    public static String getStrNoBlank(String str) {
        return str.replaceAll(" ", "")
                .replaceAll("\n", "")
                .replaceAll("[ ]", "")
                .replaceAll(" ", "");
    }


    /**
     * 首尾去除特殊字符
     */
    public static String trimSpecialChars(String str,String specialRegx) {
        String regex = "^" + specialRegx + "*|" + specialRegx + "*$";
        return str.replaceAll(regex, "");
    }


    //获得当前页
    public static Integer getPageNum(String lineId){
        String lineStr = lineId.substring(lineId.indexOf("_") + 1);
        String pageNum = lineStr.substring(0, lineStr.indexOf("_"));
        return Integer.parseInt(pageNum);
    }


    /**
     * 获得上一天的工作日（去除周末和法定节假日）
     */
    public static String getPreviousWorkDate(String str){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(str);
            return getDelayWorkDate(date,"yyyy-MM-dd",-1);
        } catch (ParseException e) {
            Log.error("scriptTool getPreviousWorkDate 方法报错："+e);
        }
        return str;
    }

    /**
     * 获得上一天的工作日（去除周末和法定节假日）
     */
    public static String getPreviousWorkDate(Date date,String dateFormat){
        return getDelayWorkDate(date,dateFormat,-1);
    }

    /**
     * 获得上一天或下一天的工作日（去除周末和法定节假日）
     * @param date 当前时间
     * @param dateFormat 返回的日期格式
     * @param amount 1代表下一天，-1代表上一天
     */
    public static String getDelayWorkDate(Date date,String dateFormat,int amount){
        Calendar cal= Calendar.getInstance();
        cal.setTime(date);
        do {
            cal.add(Calendar.DAY_OF_MONTH, amount);
        } while (checkHoliday(cal));
        SimpleDateFormat sm = new SimpleDateFormat(dateFormat);
        return sm.format(cal.getTime());
    }


    /**
     * 校验指定的日期是否在节日列表中
     * 具体节日包含哪些,可以在HolidayMap中修改
     * @param src 要校验的日期(源)
     */
    public static boolean checkHoliday(Calendar src) {

        boolean result = false;
        Map<Integer, List<Integer>> holidayList = initHolidayList(src.get(Calendar.YEAR));


        //先检查是否是周六周日(有些国家是周五周六)
        if (src.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
                || src.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
        {
            return true;
        }

        //检查是否是节假日
        if (holidayList.size() > 0){
            for (Map.Entry<Integer,List<Integer>> c : holidayList.entrySet()) {
                //对比月份和天数
                int srcMonth = src.get(Calendar.MONTH) + 1;
                int srcDate = src.get(Calendar.DAY_OF_MONTH);
                if (srcMonth == c.getKey()){
                    //当前天数在日期内
                    if (c.getValue().contains(srcDate)){
                        result = true;
                    }
                }
            }
        }

        return result;
    }

    /**
     * 初始化节日List,如果需要加入新的节日,请在这里添加
     * 加的时候请尽量使用Calendar自带的常量而不是魔鬼数字
     *
     * 注意：这里先放入当年的假期数据，后续需要后台提供一个管理假期表的数据库
     *
     * @param year 当前年份
     */
    private static Map<Integer, List<Integer>> initHolidayList(int year) {
        //TODO: 这里要去查每年的假期
        Map<Integer, List<Integer>> dates = new HashMap<>();
        //元旦（放假三天）
        dates.put(1,Arrays.asList(1,2,3,30));
        //春节
        dates.put(2,Arrays.asList(1,2,3,4,5,6));
        //清明节
        dates.put(4,Arrays.asList(3,4,5,30));
        //劳动节
        dates.put(5,Arrays.asList(1,2,3,4));
        //端午节
        dates.put(6,Arrays.asList(3,4,5));
        //中秋节
        dates.put(9,Arrays.asList(10,11,12));
        //国庆节
        dates.put(10,Arrays.asList(1,2,3,4,5,6,7));

        return dates;
    }

    /**
     * 获取假期时间
     * @param holidayName 假期名称
     * @param year 当前年份
     * 21世纪的公式为：[Y*D+C]-L
     * Y=年数后2位，D=0.2422，L=闰年数，21世纪C=4.81，20世纪=5.59
     * @return Date
     */
    public static Date getHoliday(String holidayName, int year) {
        switch (holidayName) {
            case "元旦节":
                return DateUtil.parse(year + "-1-1");
            case "春节":
                ChineseDate chinesenewYearFestival = new ChineseDate(year, 1, 1);
                return chinesenewYearFestival.getGregorianDate();
            case "清明节":
                int param = year - 2000;
                int qingmingDay = (int) (param * 0.2422 + 4.81) - param / 4;
                return DateUtil.parse(year + "-4-" + qingmingDay);
            case "劳动节":
                return DateUtil.parse(year + "-5-1");
            case "端午节":
                ChineseDate dragonBoatFestival = new ChineseDate(year, 5, 5);
                return dragonBoatFestival.getGregorianDate();
            case "中秋节":
                ChineseDate midAutumnFestival = new ChineseDate(year, 8, 15);
                return midAutumnFestival.getGregorianDate();
            case "国庆节":
                return DateUtil.parse(year + "-10-1");
            default:
                return new Date();
        }
    }

//    public static void main(String[] args) throws ParseException {
//        //计算节假日当天日期
//        //        Date date = getHoliday("中秋节", 2024);
//        //        Calendar instance = Calendar.getInstance();
//        //        instance.setTime(date);
//        //        System.out.println("时间为：" + instance.get(Calendar.YEAR));
//        //        System.out.println("时间为：" + (instance.get(Calendar.MONTH) + 1));
//        //        System.out.println("时间为：" + instance.get(Calendar.DAY_OF_MONTH));
//
//        //测试跳过节假日
////        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
////        Date parse = simpleDateFormat.parse("2022-9-13");
////        String previousWorkDate = getPreviousWorkDate(parse, "yyyy-MM-dd");
////
////        System.out.println(previousWorkDate);
//
//    }


    //===================================返回值转换=======================

    /**
     * 结构化表格结果转化为需要返回到数据库的对象
     * @param result 结构化表格结果
     * @param taskSn 任务id
     * @return List<TaskElementVO.DrawResultVO>
     */
    public static List<TaskElementVO.DrawResultVO> convertDraw(List<ParseContentVO> result, String taskSn) {

        List<TaskElementVO.DrawResultVO> drawResultVOS = new ArrayList<>();

        for (int i = 0; i < result.size(); i++) {
            ParseContentVO item = result.get(i);
            Integer second = item.getLinePos().get(1);
            second = second-1;
            TaskElementVO.DrawResultVO build = TaskElementVO.DrawResultVO.builder()
                    .type(1)
                    .childTaskSn(taskSn)
                    .text(item.getValue())
                    .businessValue(item.getValue())
                    .page(getPageNum(item.getLineId()))
                    .para_info(Collections.singletonList(item.getLineId()))
                    .pos_info(Arrays.asList(item.getLinePos().get(0),second))
                    .build();
            drawResultVOS.add(build);
        }

        return drawResultVOS;
    }

    //====================================辅助功能========================

    /**
     * 对象深拷贝
     * @param src 对象
     * @param <T> 拷贝对象
     * @return 拷贝对象
     * @throws IOException 异常
     * @throws ClassNotFoundException 异常
     */
    @SuppressWarnings("unchecked")
    public static <T> T deepCopy(T src) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);

        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream input = new ObjectInputStream(byteIn);
        T dest = (T)input.readObject();
        out.close();
        input.close();
        return dest;
    }

    @SuppressWarnings("unchecked")
    public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(src);

        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
        ObjectInputStream input = new ObjectInputStream(byteIn);
        List<T> dest = (List<T>) input.readObject();
        out.close();
        input.close();
        return dest;
    }


}
